#ifndef __FRAME_FORMAT_H__
#define __FRAME_FORMAT_H__

#include <iostream>
#include <cstring>
#include <functional>

#define FRAME_FLAG_INDEX            0
#define FRAME_FROM_INDEX            1
#define FRAME_TO_INDEX              2
#define FRAME_COMMAND_ID_INDEX      3
#define FRAME_DATA_LENGTH_INDEX     4
#define FRAME_DATA_START_ADDR_INDEX (4 + 2)
#define FRAME_HEADER_LENGTH         6
#define FRAME_CHECKSUM_INDEX(x)     (x + FRAME_DATA_START_ADDR_INDEX)
#define FRAME_CHECK_DATA_LENGTH(x)  (x + FRAME_HEADER_LENGTH)
#define FRAME_TOTAL_LENGTH(x)       (x + FRAME_HEADER_LENGTH + 2)

#define FRAME_BUFFER_LENGTH_MAX     65536
#define FRAME_FLAG                  0xFE
#define CHECKSUM_INIT_VALUE         0xA1B2

//帧类型为测试
#define FRAME_COMMAND_TEST          0xFF

//测试项识别标志列表
#define TEST_AUDIO_CABLE_INSERT     0x01
#define TEST_MODE_BUTTON            0x02
#define TEST_PTT_BUTTON             0x03
#define TEST_INFRARED_LAMP          0x04
#define TEST_MICROPHONE             0x05
#define TEST_SPEAKER                0x06
#define TEST_CAMERA_MODULE          0x07
#define TEST_WIFI_CONNECT           0x08
#define TEST_LIP_RECOGNITION        0x09

//测试操作标志
#define TEST_START                  0xF0
#define TEST_STOP                   0xF1
#define TEST_STARTED                0xF2
#define TEST_STOPED                 0xF3
#define TEST_TRANSFER_WLAN_IP       0xF4

//
#define TEST_LOG_FLAG               0

typedef struct{
    uint8_t     flag;       //帧头标志
    uint8_t     from;       //数据来着哪个设备
    uint8_t     to;         //数据到哪个设备
    uint8_t     command_id; //指令id
    uint16_t    data_length;//数据长度
    uint8_t     *data;      //数据内容
    uint16_t    check_code; //校验码
}TestModuleFrameContent;

typedef int   (*recv_command_data_callback_func)(TestModuleFrameContent data);

class TestModuleFrameFormat
{
public:
    TestModuleFrameFormat();

    int highConvertToLow(void *data_out, void *data_in, uint16_t length);
    uint16_t calcCrc16(const uint8_t *buffer, uint32_t size, uint16_t crc);
    void register_recv_command_data_callback(std::function<void(TestModuleFrameContent)> callback);
    int frame_analysis_function(void *data, unsigned int length);
    int framePackageFunction(void *data_in, uint16_t length);

private:
    std::function<void(TestModuleFrameContent)> callback_func;
    unsigned char  data_buffer[FRAME_BUFFER_LENGTH_MAX];
    unsigned char  save_buffer[FRAME_BUFFER_LENGTH_MAX];
    unsigned short save_data_length;
};

#endif
